---
layout: default
title: Comparisons
---

<div class="hgroup">
  <div class="hgroup-inline">
    <div class="panel">
      <h1 id="comparisons">Comparisons</h1>
    </div>
    <div style="clear: both"></div>
  </div>
</div>

<div class="hgroup">
  <div class="hgroup-inline">
    <div class="panel">
      <p>
        This article attempts to describe the whole open source configuration space, and Jsonnet's
        place within it.  Needless to say this is challenging and this will be a living document.
      </p>
    </div>
    <div style="clear: both"></div>
  </div>
</div>

<div class="hgroup">
  <div class="hgroup-inline">
    <div class="panel">
        <h2 id="json">Comparison With JSON</h2>
    </div>
    <div style="clear: both"></div>
  </div>
</div>

<div class="hgroup">
  <div class="hgroup-inline">
    <div class="panel">
      <p>
        JSON is used to describe data literally.  Jsonnet extends JSON.  Jsonnet has relaxed syntax
        and comments to make it easier for humans to write.  Jsonnet also adds constructs for
        generating, translating and refining data.  Because Jsonnet is an extension of JSON, valid
        JSON is also valid Jsonnet that just emits that JSON unchanged.
      </p>
    </div>
    <div style="clear: both"></div>
  </div>
</div>


<div class="hgroup">
  <div class="hgroup-inline">
    <div class="panel">
      <h2 id="yaml">Comparison With YAML</h2>
    </div>
    <div style="clear: both"></div>
  </div>
</div>

<div class="hgroup">
  <div class="hgroup-inline">
    <div class="panel">
      <p>
        YAML is also an extension of JSON that generates JSON.  Like Jsonnet, YAML is intended to
        improve the user experience when data is transferred over the human / machine boundary.  Its
        syntax is very tight; YAML files are much shorter than their JSON equivalents.  However its
        constructs for generating, translating, and refining data are very weak in comparison to
        Jsonnet.  Moreover, the tightness of its syntax makes it hard to extend YAML to add these
        features.  In particular, YAML and Jsonnet disagree about what 1+1 should mean.  YAML
        already defines it to mean the string "1+1", whereas in Jsonnet we want it to be 2.  Jsonnet
        therefore builds from JSON and not YAML.
      </p>
    </div>
    <div style="clear: both"></div>
  </div>
</div>


<div class="hgroup">
  <div class="hgroup-inline">
    <div class="panel">
      <h2 id="templates">Comparison With Other Templating Languages</h2>
    </div>
    <div style="clear: both"></div>
  </div>
</div>

<div class="hgroup">
  <div class="hgroup-inline">
    <div class="panel">
      <p>
        Jsonnet is a form of templating language as it generates data from programs that interleave
        verbatim data with computation constructs.  However other templating languages operate on
        plain text.  That is to say that the data amongst which the computational constructs are
        intermingled are simply plain text, and the output of the evaluation is also plain text.
        This means such systems can be used to produce files with arbitrary syntax, e.g. custom
        configuration file syntax, HTML, or even JSON.
      </p>

      <p>
        However, since these templating languages are unaware of the syntax of the file they're
        generating (they think it is simply plain text), they cannot help the programmer avoid
        creating errors in the underlying representation.
      </p>

      <p>
        By analogy, the C preprocessor has no understanding of C syntax.  C preprocessor macros can
        break that syntax if they are used wrongly.  The net result of this is that problems with
        the use of these macros must be debugged by examining the output of the evaluation (i.e. the
        generated C code).  Errors cannot be presented at the level at which the programmer is
        actually working.  For this reason, the vast majority of modern languages do not feature a
        pre-processor.
      </p>

      <p>
        The situation is the same when templating languages are used to generate HTML, often the
        developer will check the generated HTML because successful evaluation of the template does
        not imply the HTML is correct.  The same is true when the target language is JSON.  Jsonnet
        avoids these problems, as although it is limited to JSON output, it is guaranteed that the
        output will be valid JSON.
      </p>
    </div>
    <div style="clear: both"></div>
  </div>
</div>


<div class="hgroup">
  <div class="hgroup-inline">
    <div class="panel">
      <h2 id="functional">Comparison With Other Functional Languages</h2>
    </div>
    <div style="clear: both"></div>
  </div>
</div>

<div class="hgroup">
  <div class="hgroup-inline">
    <div class="panel">
      <p>
        ML is a functional language like Jsonnet.  However ML is not pure, and also has strict
        evaluation.  Haskell is a pure lazy functional language, but unlike Jsonnet it has static
        type safety.  Providing static type safety means programmers have to understand type
        inference, unification errors, and also provide the occasional type annotation.  Even then,
        some correct programs are rejected.
      </p>
      <p>
        The Nix expression language, which is a pure lazy functional language with dynamic typing,
        is therefore closer to Jsonnet.  Jsonnet differs from the Nix expression language mainly in
        that it also has object-oriented semantics in the form of mixins.  Also, Jsonnet is an
        extension of JSON, whereas the Nix expression language is not (in particular it lacks
        floating point numbers).  Finally, the Nix expression language is an embedded part of the
        Nix package manager (and other tools), whereas Jsonnet is a standalone evaluator that can
        sit in front of anything that accepts JSON.
      </p>
    </div>
    <div style="clear: both"></div>
  </div>
</div>


<div class="hgroup">
  <div class="hgroup-inline">
    <div class="panel">
      <h2 id="scripting">Comparison With Other Scripting Languages</h2>
    </div>
    <div style="clear: both"></div>
  </div>
</div>

<div class="hgroup">
  <div class="hgroup-inline">
    <div class="panel">
      <p>
        Most scripting languages are dynamically typed languages, often with object-oriented
        features.
      </p>

      <p>
        However, Jsonnet is also a templating language, which makes it very good for generating data
        that is a mixture of verbatim and computed elements.  Jsonnet programs can be easily
        understood and modified by someone who only knows JSON.  Any parts of the program which are
        just JSON (i.e. do not make use of the extended Jsonnet constructs) can be modified with
        predictable results.  Jsonnet's pure functional semantics also make modifying the program
        more predictable.
      </p>

      <p>
        More importantly, Jsonnet has the property of hermeticity.  This means that regardless of
        when or where a Jsonnet program is evaluated, it will always generate the same JSON.  This
        means the program can be freely converted to data, and thus it can be thought of as
        equivalent to data.  This is not the case with general purpose languages, as they are
        allowed to read files, contact the network, look up the time, or any number of other sources
        of non-deterministic behavior.  While it is possible to sandbox some scripting languages in
        order to patch all of these holes, the result of this is a new language that is incompatible
        with the original language.  This makes Jsonnet a lot more suitable for configuration than
        general purpose scripting languages.
      </p>

      <p>
        One advantage that is often put forward for using general purpose scripting languages as
        configuration languages is that they are already well-understood by a large number of
        people.  However this is also true of Jsonnet, because of its backwards compatibility with
        JSON, its use of mixins (a decades old construct that is well-understood) and the mimicking
        of Python syntax in cases where that makes sense (e.g. string formatting and comprehension
        constructs).
      </p>

      <p>
        Finally, Jsonnet is a much smaller language than most general purpose scripting languages,
        yet despite this it has considerable expressive power.
      </p>
    </div>
    <div style="clear: both"></div>
  </div>
</div>


<div class="hgroup">
  <div class="hgroup-inline">
    <div class="panel">
      <h2 id="configuration">Comparison With Other Configuration Languages</h2>
    </div>
    <div style="clear: both"></div>
  </div>
</div>

<div class="hgroup">
  <div class="hgroup-inline">
    <div class="panel">
      <p>
        <a href="https://code.google.com/p/coil/">Coil</a> is a configuration language that is
        interpreted by a Python library.  Like Jsonnet, it has a JSON-like data model and some
        facilities for extending objects to avoid duplication, referring to other parts of the
        structure, and importing from other files.  However it is a long way from the expressiveness
        of the object-oriented semantics of Jsonnet, and it also does not have the ability to do
        arithmetic beyond substituting values into strings.  Finally, coil binds variables according
        to <a href="https://en.wikipedia.org/wiki/Scope_(computer_science)#Dynamic_scope">dynamic
        scoping rules</a>, which have long been discredited because they quickly make code very
        difficult to understand.  Jsonnet uses static scoping, like almost all mainstream languages.
      </p>
      <p>
        <a href="https://github.com/wickman/pystachio">Pystachio</a> is a Python framework that
        makes it easier to use Python itself as a configuration language.  It extends Python's
        existing data literals (which are JSON-like) to enforce immutability and add some templating
        functionality.  However it lacks the full computational abilities of Jsonnet.  Although it
        does allow some computation within string values via template expansion, the only variables
        you can access are stored in separate "environments", and there is no direct access to the
        data being configured.  Even if we assume that all data is stored in environments and object
        fields merely forward to the environment, the language does not have any true
        object-orientation features.  While scopes are inherited from outer objects, this just an
        implicit way of doing what you can do in Jsonnet with <code>$</code> or <code>local</code>.
        In Pystachio there is no way to derive a struct from another struct with a few changes, let
        alone use late binding or the expressive power of mixins.
      </p>
      <p>
        Finally, there are a number of other configuration languages that have grown to be used by a
        range of applications.  For example <a href="https://en.wikipedia.org/wiki/INI_file">INI
        files</a> or <a href="https://httpd.apache.org/docs/2.2/configuring.html">Apache config
        files</a>.  Typically these offer few features beyond simple JSON and provide very little
        functionality when compared to Jsonnet.
      </p>
    </div>
    <div style="clear: both"></div>
  </div>
</div>
